﻿using System.Windows;
using System.ComponentModel;

namespace Geometry
{
    public sealed class FreePoint : GObjectBase, IGPoint, IDraggable
    {
        public FreePoint()
        {
            m_Position = new Point();
            UpdateBoundingBox();
        }

        public FreePoint(Point p)
        {
            m_Position = p;
            UpdateBoundingBox();
        }

        public FreePoint(double x, double y)
        {
            m_Position = new Point(x, y);
            UpdateBoundingBox();
        }

        protected override void ReleaseDependencies()
        {
            // Free points have no dependency
        }

        #region IGPoint Members

        private Point m_Position;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public double PosX
        {
            get { return m_Position.X; }
            set
            {
                if (value.Equals(m_Position.X)) return;
                m_Position.X = value;
                UpdateBoundingBox();
                RaisePropertyChanged("PosX");
                RaisePropertyChanged("Position");
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public double PosY
        {
            get { return m_Position.Y; }
            set
            {
                if (value.Equals(m_Position.Y)) return;
                m_Position.Y = value;
                UpdateBoundingBox();
                RaisePropertyChanged("PosY");
                RaisePropertyChanged("Position");
            }
        }

        public Point Position
        {
            get { return m_Position; }
            set
            {
                if (value.Equals(m_Position)) return;
                m_Position = value;
                UpdateBoundingBox();
                RaisePropertyChanged("Position");
                RaisePropertyChanged("PosX");
                RaisePropertyChanged("PosY");
            }
        }

        #endregion

        #region IDraggable Members
        private Point m_BeginDragPoint;
        private bool m_IsDragged = false;

        public void BeginDrag()
        {
            m_BeginDragPoint = m_Position;
        }

        public void EndDrag()
        {
            m_IsDragged = false;
        }

        public void CancelDrag()
        {
            Position = m_BeginDragPoint;
            m_IsDragged = false;
        }

        public void DragBy(Vector amount)
        {
            Position = m_Position + amount;
            m_IsDragged = true;
        }

        public bool IsDragged
        {
            get { return m_IsDragged; }
        }

        #endregion

        protected override void UpdateBoundingBox()
        {
            base.BoundingBox = new Rect(Position, Position);
        }
    }

}
